package cn._2dland.video
{
	import cn._2dland.events.VideoStreamEvent;
	import cn._2dland.utils.VideoUtils;
	
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.NetStatusEvent;
	import flash.media.SoundTransform;
	import flash.media.Video;
	import flash.net.NetConnection;
	import flash.net.NetStream;

	[Event(name="streamReady", type="cn._2dland.events.VideoStreamEvent")]
	[Event(name="streamError", type="cn._2dland.events.VideoStreamEvent")]
	[Event(name="streamPlay", type="cn._2dland.events.VideoStreamEvent")]
	[Event(name="streamPause", type="cn._2dland.events.VideoStreamEvent")]
	[Event(name="streamStop", type="cn._2dland.events.VideoStreamEvent")]

	/**
	 * 视频流类：封装了NetStream的事件处理
	 * @author deadblue
	 */	
	public class VideoStream extends EventDispatcher
	{
		private var _nc:NetConnection;
		private var _ns:NetStream = null;
		private var _info:StreamInfo = null;

		public function VideoStream(netConn:NetConnection, info:StreamInfo) {
			this._nc = netConn;
			this._info = info;

			_ns = new NetStream(_nc);
			_ns.bufferTime = VideoUtils.BUFFER_TIME;
			_ns.client = this;

			removeHandlers();
			addHandlers();
		}

		/*******************************************************/
		public function get info():StreamInfo {
			return _info;
		}
		public function get stream():NetStream {
			return _ns;
		}
		public function get percent():Number {
			if(_ns == null) return 0;
			if(_ns.bytesLoaded == _ns.bytesTotal) return 1;
			return (Number)(_ns.bytesLoaded / _ns.bytesTotal);
		}
		public function set volumn(vol:Number):void {
			if(_ns == null) return;
			_ns.soundTransform = new SoundTransform(vol);
		}

		/*******************************************************/
		public function buffer():void {
			if(_ns == null) return;
			_ns.play(_info.url);
		}

		public function play():void {
			if(_ns == null) return;
			_ns.resume();
		}

		public function pause():void {
			if(_ns == null) return;
			_ns.pause();
		}

		public function seek(time:Number):void {
			if(_ns == null) return;
			_ns.seek(time);
		}

		/*******************************************************/
		/** 添加事件监听器 */
		private function addHandlers():void {
			if(_ns == null) return;
			_ns.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
			_ns.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
		}
		/** 移除事件监听器 */
		private function removeHandlers():void {
			if(_ns == null) return;
			if(_ns.hasEventListener(NetStatusEvent.NET_STATUS))
				_ns.removeEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
			if(_ns.hasEventListener(IOErrorEvent.IO_ERROR))
				_ns.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
		}

		/*******************************************************/
		/** 联网状态变化 */
		protected function netStatusHandler(e:NetStatusEvent):void {
			switch(e.info.code){
				case "NetStream.Buffer.Empty":
					break;
				case "NetStream.Buffer.Full":
					break;
				case "NetStream.Buffer.Flush":
					break;
				case "NetStream.Play.Start":
					pause();
					break;
				case "NetStream.Play.Stop":
					dispatchEvent(new VideoStreamEvent(VideoStreamEvent.STREAM_STOP));
					break;
				case "NetStream.Play.Failed":
				case "NetStream.Play.StreamNotFound":
				case "NetStream.Play.FileStructureInvalid":
				case "NetStream.Play.NoSupportedTrackFound":
					dispatchEvent(new VideoStreamEvent(VideoStreamEvent.STREAM_ERROR));
					break;
				case "NetStream.Pause.Notify":
					dispatchEvent(new VideoStreamEvent(VideoStreamEvent.STREAM_PAUSE));
					break;
				case "NetStream.Unpause.Notify":
					dispatchEvent(new VideoStreamEvent(VideoStreamEvent.STREAM_PLAY));
					break;
				case "NetStream.Seek.Failed":
					break;
				case "NetStream.Seek.InvalidTime":
					break;
				case "NetStream.Seek.Notify":
					break;
			}
		}
		/** 异步错误 */
		protected function ioErrorHandler(e:IOErrorEvent):void {
			removeHandlers();
			dispatchEvent(new VideoStreamEvent(VideoStreamEvent.STREAM_ERROR));
		}
		/** 头数据到达 */
		public function onMetaData(data:Object):void {
			// 更新视频流信息
			if(data.hasOwnProperty("duration")){
				var realDuration:Number = data.duration * 1000;
				_info.durationFix = realDuration - _info.duration;
				_info.duration = realDuration;
			}
			if(data.hasOwnProperty("width"))
				_info.width = data.width;
			if(data.hasOwnProperty("height"))
				_info.height = data.height;
			_info.ready = true;
			
			dispatchEvent(new VideoStreamEvent(VideoStreamEvent.STREAM_READY));
		}
		public function onCuePoint(data:Object):void{ }
		public function onLastSecond(data:Object=null):void{ }
		public function onPlayStatus(data:Object=null):void{ }
	}
}